﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SimulacionAgrofoods
{
    public class Frio
    {
        string _nombre = "";
        int _costo_total = 0;
        int _costo_fijo = 0;
        int _costo_variable = 0;
        int _costo_dia_extra = 0;
        int _numeral = 0;
        bool _frio_fijo = false;
        int _capacidad_maxima = 0;
        int _capacidad_camara = 0;
        int _zona = 0;
        List<Lote> _lotes;
        int _tiempo_lotes = 0;
        bool _frio_interno = false;
        int _llegada_dia = 0;

        int _bins_totales_recibidos = 0;
        int _costos_bins_enviados = 0;

        public Frio(int Capacidad_Maxima, int Capacidad_Camara, string Nombre)
        {
            _nombre = Nombre;
            _capacidad_camara = Capacidad_Camara;
            _frio_interno = true;
            _capacidad_maxima = Capacidad_Maxima;
            _lotes = new List<Lote>();
        }


        /// <summary>
        /// Constructor para un Frio Fijo
        /// </summary>
        /// <param name="Costo_Fijo"></param>
        /// <param name="Capacidad_Maxima"></param>
        public Frio(int Costo_Fijo, int Capacidad_Maxima, int Zona, int Capacidad_Camara, string Nombre) 
        {
            _nombre = Nombre;
            _capacidad_camara = Capacidad_Camara;
            _costo_fijo = Costo_Fijo;
            _capacidad_maxima = Capacidad_Maxima;
            _zona = Zona;
            _lotes = new List<Lote>();
        
        }

        /// <summary>
        /// Constructor Frio Variable
        /// </summary>
        /// <param name="Costo_Variable"></param>
        /// <param name="Numeral"></param>
        /// <param name="Capacidad_Maxima"></param>
        /// <param name="Zona"></param>
        public Frio(int Costo_Variable, int Numeral, int Capacidad_Maxima, int Zona, int Capacidad_Camara, string Nombre) 
        {
            _nombre = Nombre;
            _capacidad_camara = Capacidad_Camara;
            _costo_variable = Costo_Variable;
            _numeral = Numeral;
            _capacidad_maxima = Capacidad_Maxima;
            _zona = Zona;
            _lotes = new List<Lote>();
            
        }

        public void Llega_Lote(Lote Lote_Llegada) 
        {
            //Le asignamos al lote que lleva 0 dias en 
            Lote_Llegada.Llegada_Frio = 0;
           
            _lotes.Add(Lote_Llegada);

            if (!_frio_fijo) { _costo_total += _costo_variable * Lote_Llegada.Cantidad; }

            _llegada_dia += Lote_Llegada.Cantidad;

            _bins_totales_recibidos += Lote_Llegada.Cantidad;
        }

        public List<Lote> Enviar_Lote_Vencidos(int venc) 
        {
            List<Lote> vencidos=new List<Lote>();
            if (_lotes.Count > 0)
            {
                vencidos = (from Lote l in _lotes
                            where l.Vencimiento <= venc
                            select l).ToList();
            }

            foreach (Lote l in vencidos) 
            {
                _lotes.Remove(l);
            }

            if (_lotes.Count == 0) {
                _costo_total += (int)((double)((double)_tiempo_lotes / (double)30) * _costo_fijo);
                _tiempo_lotes = 0;
            }

            return vencidos;
        
        }

        public Lote Enviar_Lote(Lote Lote_Pedido) {
            _lotes.Remove(Lote_Pedido);


            if (_lotes.Count > 0 && _frio_fijo) {


                _costo_total += (int)((double)((double)_tiempo_lotes / (double)30) * _costo_fijo);
                _tiempo_lotes = 0;

            }

            return Lote_Pedido;

        }

        public Lote get_lote_minimo() {
            if (_lotes.Count>0)
            {
                List<Lote> lotesordenados = _lotes.OrderBy(x => x.Vencimiento).ToList();

                return lotesordenados[0];

            }
            else return null;
        }

        public int get_Costos() {
            
            return _costo_total;
        }

        public void Cambio_Dia() 
        {

            foreach (Lote l in _lotes) {
                l.Vencimiento = l.Vencimiento - 1;
                l.Llegada_Frio = l.Llegada_Frio + 1;

                if (!_frio_fijo && l.Llegada_Frio > _numeral) { _costo_total += _costo_dia_extra*l.Cantidad; }

            }


            if (_lotes.Count > 0) _tiempo_lotes++;

            _llegada_dia = 0;
        
        }

        public void Calcular_Costos_Fijo() 
        { 
        
        }

        public void Calcular_Costos_Variables() 
        { 
        
        }

        public int Capacidad_Sobrante() 
        {
            int capacidad = _capacidad_maxima;
            foreach(Lote l in _lotes)
            {
                capacidad = capacidad - l.Cantidad;
            }
            return capacidad;
        }

        public int Duracion_Lote_Minimo() 
        {
            if (_lotes.Count > 0)
            {
                List<Lote> lotesordenados = _lotes.OrderBy(x => x.Vencimiento).ToList();
                return lotesordenados[0].Vencimiento;
            }
            else 
            {
                return 1000;
            }
        }

        public int Zona { get { return _zona; } }

        public bool Interno { get { return _frio_interno; } set { _frio_interno = value; } }

        public int Llegada_Día { get { return _llegada_dia; } set { _llegada_dia = value; } }

        public int Capacidad_Enfriamiento { get { return _capacidad_camara; } set { _capacidad_camara = value; } }

        public string Nombre { get { return _nombre; } }

        public int Bins_Totales { get { return _bins_totales_recibidos; } set { _bins_totales_recibidos = value; } }

        public int Costos_Envios { get { return _costos_bins_enviados; } set { _costos_bins_enviados = value; } }

    }
}
